home *** CD-ROM | disk | FTP | other *** search
- #include "stdafx.h"
-
- cCharacter::cCharacter(cProperties *_orig)
- : cGameObject(_orig)
- {
- // Get animations
-
- orig->get_sequence("WALK LEFT", walk_left_seq);
- orig->get_sequence("WALK RIGHT", walk_right_seq);
- orig->get_sequence("WALK LEFT RIGHT", walk_left_right_seq);
- orig->get_sequence("WALK FIRE LEFT", walk_fire_left_seq);
- orig->get_sequence("WALK FIRE RIGHT", walk_fire_right_seq);
- orig->get_sequence("WALK FIRE UP", walk_fire_up_seq);
-
- orig->get_sequence("JUMP LEFT", jump_left_seq);
- orig->get_sequence("JUMP RIGHT", jump_right_seq);
- orig->get_sequence("JUMP LEFT RIGHT", jump_left_right_seq);
- orig->get_sequence("JUMP FIRE LEFT", jump_fire_left_seq);
- orig->get_sequence("JUMP FIRE RIGHT", jump_fire_right_seq);
- orig->get_sequence("JUMP FIRE UP LEFT", jump_fire_up_left_seq);
- orig->get_sequence("JUMP FIRE UP RIGHT", jump_fire_up_right_seq);
-
- orig->get_sequence("DUCK LEFT", duck_left_seq);
- orig->get_sequence("DUCK RIGHT", duck_right_seq);
- orig->get_sequence("DUCK LEFT RIGHT", duck_left_right_seq);
- orig->get_sequence("DUCK FIRE LEFT", duck_fire_left_seq);
- orig->get_sequence("DUCK FIRE RIGHT", duck_fire_right_seq);
-
- orig->get_sequence("JET LEFT", jet_left_seq);
- orig->get_sequence("JET RIGHT", jet_right_seq);
- orig->get_sequence("JET LEFT RIGHT", jet_left_right_seq);
- orig->get_sequence("JET FIRE LEFT", jet_fire_left_seq);
- orig->get_sequence("JET FIRE RIGHT", jet_fire_right_seq);
- orig->get_sequence("JET FIRE UP LEFT", jet_fire_up_left_seq);
- orig->get_sequence("JET FIRE UP RIGHT", jet_fire_up_right_seq);
- orig->get_sequence("JET ON LEFT", jet_on_left_seq);
- orig->get_sequence("JET ON RIGHT", jet_on_right_seq);
- orig->get_sequence("JET OFF LEFT", jet_off_left_seq);
- orig->get_sequence("JET OFF RIGHT", jet_off_right_seq);
-
- orig->get_sequence("KICK LEFT", kick_left_seq);
- orig->get_sequence("KICK RIGHT", kick_right_seq);
-
- orig->get_sequence("STUNNED", stunned_seq);
- orig->get_sequence("CAPTURED", captured_seq);
- orig->get_sequence("CLIMBING", climbing_seq);
-
- // Set boundaries
-
- orig->get_circles("STANDING", &bounds_standing);
- orig->get_circles("DUCKED", &bounds_ducked);
-
- // Circles for kick
-
- orig->get_circles("KICK LEFT", &kick_left_circle);
- orig->get_circles("KICK RIGHT", &kick_right_circle);
-
- // Set spots
-
- orig->get_spots("WALK FIRE LEFT", &walk_fire_left_spot);
- orig->get_spots("WALK FIRE RIGHT", &walk_fire_right_spot);
- orig->get_spots("WALK FIRE UP", &walk_fire_up_spot);
-
- orig->get_spots("JUMP FIRE LEFT", &jump_fire_left_spot);
- orig->get_spots("JUMP FIRE RIGHT", &jump_fire_right_spot);
- orig->get_spots("JUMP FIRE UP LEFT", &jump_fire_up_left_spot);
- orig->get_spots("JUMP FIRE UP RIGHT", &jump_fire_up_right_spot);
-
- orig->get_spots("JET FIRE LEFT", &jet_fire_left_spot);
- orig->get_spots("JET FIRE RIGHT", &jet_fire_right_spot);
- orig->get_spots("JET FIRE UP LEFT", &jet_fire_up_left_spot);
- orig->get_spots("JET FIRE UP RIGHT", &jet_fire_up_right_spot);
-
- orig->get_spots("DUCK FIRE LEFT", &duck_fire_left_spot);
- orig->get_spots("DUCK FIRE RIGHT", &duck_fire_right_spot);
-
- orig->get_spots("FIRE DOWN", &fire_down_spot);
-
- // Get sounds
-
- orig->get_soundsequence("GOT HIT", snd_gothit);
-
- // Clear weapons
-
- weapon = 0;
- weapon_down = 0;
-
- // Reset score counters
-
- deaths = 0;
- stuns = 0;
- shots_fired = 0;
-
- // Set text stuff
-
- text_above_char = new cText (&texts);
- text_above_char->set_centered(TRUE);
-
- // Setup other variables
-
- influenced_by_catapult = TRUE;
- influenced_by_inpenetrable = TRUE;
-
- // Revive character and put it in a bubble
-
- revive();
- }
-
- void cCharacter::revive()
- {
- // Set some variables
-
- stop_movement();
-
- ay = GRAVITY;
-
- armor = orig->params->get_int("*ARMOR", 100);
-
- ducked = FALSE;
- circle_bounds = bounds_standing;
-
- standing = FALSE;
- climbing = FALSE;
- captured = 0;
-
- dead = FALSE;
-
- jetpack_active = FALSE;
- jetpack_time = JETPACK_TIME;
-
- stunned = 0;
- firing = 0;
- ignore_platforms = 0;
- next_stun_time = 2 * sec;
- invulnerable = CHAR_INVULNERABLE;
-
- last_move = CHAR_LEFT;
- horiz_speed = 0;
- set_last_in_sequence(jump_left_seq);
-
- // Weapon is standard gun
-
- weapon->delete_list();
- new cInventoryBullet(&weapon);
-
- weapon_down->delete_list();
- }
-
- cCharacter::~cCharacter()
- {
- // Delete weapons
-
- weapon->delete_list();
- weapon_down->delete_list();
-
- // Delete boundaries
-
- bounds_standing->delete_list();
- bounds_ducked->delete_list();
-
- // Delete circles
-
- kick_left_circle->delete_list();
- kick_right_circle->delete_list();
-
- // Delete spots
-
- walk_fire_left_spot->delete_list();
- walk_fire_right_spot->delete_list();
- walk_fire_up_spot->delete_list();
-
- jump_fire_left_spot->delete_list();
- jump_fire_right_spot->delete_list();
- jump_fire_up_left_spot->delete_list();
- jump_fire_up_right_spot->delete_list();
-
- duck_fire_left_spot->delete_list();
- duck_fire_right_spot->delete_list();
-
- jet_fire_left_spot->delete_list();
- jet_fire_right_spot->delete_list();
- jet_fire_up_left_spot->delete_list();
- jet_fire_up_right_spot->delete_list();
-
- fire_down_spot->delete_list();
-
- // Delete text
-
- delete text_above_char;
- }
-
- void cCharacter::set_horiz_speed(int new_speed)
- {
- // First substract old speed
-
- vx -= (fix)horiz_speed;
-
- // Add new speed
-
- vx += new_speed;
-
- // Remember new speed
-
- horiz_speed = new_speed;
- }
-
- void cCharacter::walk_turn_left()
- {
- if (last_move != CHAR_LEFT)
- set_inverse_sequence(walk_left_right_seq);
-
- last_move = CHAR_LEFT;
- }
-
- void cCharacter::walk_left()
- {
- walk_turn_left();
-
- set_horiz_speed(-CHAR_WALK_SPEED);
- }
-
- void cCharacter::walk_turn_right()
- {
- if (last_move != CHAR_RIGHT)
- set_sequence(walk_left_right_seq);
-
- last_move = CHAR_RIGHT;
- }
-
- void cCharacter::walk_right()
- {
- walk_turn_right();
-
- set_horiz_speed(CHAR_WALK_SPEED);
- }
-
- void cCharacter::walk_h_halt()
- {
- cAnimation c = get_sequence();
-
- if (c.start_frame == walk_left_seq.start_frame || c.start_frame == walk_right_seq.start_frame)
- stop_animation();
-
- set_horiz_speed(0);
- }
-
- void cCharacter::climb_turn_left()
- {
- last_move = CHAR_LEFT;
- }
-
- void cCharacter::climb_left()
- {
- climb_turn_left();
-
- set_horiz_speed(-CHAR_CLIMB_SPEED);
- }
-
- void cCharacter::climb_turn_right()
- {
- last_move = CHAR_RIGHT;
- }
-
- void cCharacter::climb_right()
- {
- last_move = CHAR_RIGHT;
-
- set_horiz_speed(CHAR_CLIMB_SPEED);
- }
-
- void cCharacter::climb_up()
- {
- vy = CHAR_CLIMB_SPEED;
- }
-
- void cCharacter::climb_down()
- {
- vy = -CHAR_CLIMB_SPEED;
- }
-
- void cCharacter::climb_h_halt()
- {
- set_horiz_speed(0);
- }
-
- void cCharacter::climb_v_halt()
- {
- vy = 0;
- }
-
- void cCharacter::jet_on()
- {
- if (!jetpack_active && jetpack_time > 0)
- {
- ay = 0;
- vy = 0;
-
- jetpack_active = TRUE;
- jetpack_timer = 0;
-
- set_sequence(last_move == CHAR_LEFT? jet_on_left_seq:jet_on_right_seq);
- }
- }
-
- void cCharacter::jet_off()
- {
- if (jetpack_active)
- {
- ay = GRAVITY;
-
- jetpack_active = FALSE;
-
- set_sequence(last_move == CHAR_LEFT? jet_off_left_seq:jet_off_right_seq);
- }
- }
-
- void cCharacter::jet_turn_left()
- {
- if (last_move != CHAR_LEFT)
- set_inverse_sequence(jet_left_right_seq);
-
- last_move = CHAR_LEFT;
- }
-
- void cCharacter::jet_left()
- {
- jet_turn_left();
-
- set_horiz_speed(-JETPACK_SPEED);
- }
-
- void cCharacter::jet_turn_right()
- {
- if (last_move != CHAR_RIGHT)
- set_sequence(jet_left_right_seq);
-
- last_move = CHAR_RIGHT;
- }
-
- void cCharacter::jet_right()
- {
- jet_turn_right();
-
- set_horiz_speed(JETPACK_SPEED);
- }
-
- void cCharacter::jet_up()
- {
- vy = JETPACK_SPEED;
- }
-
- void cCharacter::jet_down()
- {
- vy = -JETPACK_SPEED;
- }
-
- void cCharacter::jet_h_halt()
- {
- set_horiz_speed(0);
- }
-
- void cCharacter::jet_v_halt()
- {
- vy = 0;
- }
-
- void cCharacter::jump()
- {
- stand();
-
- vy = CHAR_JUMP_SPEED;
-
- set_sequence(last_move == CHAR_LEFT? jump_left_seq:jump_right_seq);
- }
-
- void cCharacter::jump_turn_left()
- {
- if (last_move != CHAR_LEFT)
- set_inverse_sequence(jump_left_right_seq);
-
- last_move = CHAR_LEFT;
- }
-
- void cCharacter::jump_left()
- {
- jump_turn_left();
-
- set_horiz_speed(-CHAR_WALK_SPEED);
- }
-
- void cCharacter::jump_turn_right()
- {
- if (last_move != CHAR_RIGHT)
- set_sequence(jump_left_right_seq);
-
- last_move = CHAR_RIGHT;
- }
-
- void cCharacter::jump_right()
- {
- jump_turn_right();
-
- set_horiz_speed(CHAR_WALK_SPEED);
- }
-
- void cCharacter::jump_h_halt()
- {
- set_horiz_speed(0);
- }
-
- void cCharacter::duck()
- {
- if (standing && !ducked)
- {
- ducked = TRUE;
- circle_bounds = bounds_ducked;
-
- set_horiz_speed(0);
-
- set_sequence(last_move == CHAR_LEFT? duck_left_seq:duck_right_seq);
- }
- }
-
- void cCharacter::duck_left()
- {
- if (last_move != CHAR_LEFT)
- set_inverse_sequence(duck_left_right_seq);
-
- last_move = CHAR_LEFT;
- }
-
- void cCharacter::duck_right()
- {
- if (last_move != CHAR_RIGHT)
- set_sequence(duck_left_right_seq);
-
- last_move = CHAR_RIGHT;
- }
-
- void cCharacter::stand()
- {
- circle_bounds = bounds_standing;
-
- if (ducked)
- {
- ducked = FALSE;
-
- set_inverse_sequence(last_move == CHAR_LEFT? duck_left_seq:duck_right_seq);
- add_last_in_sequence(last_move == CHAR_LEFT? walk_left_seq:walk_right_seq);
- }
- }
-
- void cCharacter::fire()
- {
- cCharacter *ch;
- cCircle *c;
-
- if (weapon == 0 || firing)
- return;
-
- // Increase shots fired
-
- shots_fired++;
-
- // Check kick distance
-
- c = last_move == CHAR_LEFT? kick_left_circle:kick_right_circle;
- ch = (cCharacter *)check_radial_boundaries(c, players);
-
- if (ch != 0 && captured == 0 && ch->captured == 0)
- {
- firing = CHAR_KICK_DLY;
-
- int was_active = ch->is_active();
-
- // Do kick and push
-
- ch->push(angle(c->x, 10), CHAR_KICK_POWER);
- ch->hit(CHAR_KICK_APOWER);
-
- // Create effect and set animation
-
- new cEffect (x + c->x, y - c->y, orig, "KICK EFFECT");
- set_sequence(last_move == CHAR_LEFT? kick_left_seq:kick_right_seq);
-
- // Award points if other character was active
-
- if (was_active)
- modify_score(30 + (ch->is_active()? 0 : 50), ch);
- }
- else
- {
- firing = weapon->fire_delay;
-
- if (last_move == CHAR_LEFT)
- {
- if (captured != 0)
- {
- delete captured;
- }
- else if (jetpack_active)
- {
- set_sequence(jet_fire_left_seq);
- weapon->fire(jet_fire_left_spot, x, y, 128, this);
- }
- else if (ducked)
- {
- set_sequence(duck_fire_left_seq);
- weapon->fire(duck_fire_left_spot, x, y, 128, this);
- }
- else if (standing)
- {
- set_sequence(walk_fire_left_seq);
- weapon->fire(walk_fire_left_spot, x, y, 128, this);
- }
- else
- {
- set_sequence(jump_fire_left_seq);
- weapon->fire(jump_fire_left_spot, x, y, 128, this);
- }
- }
- else
- {
- if (captured != 0)
- {
- delete captured;
- }
- else if (jetpack_active)
- {
- set_sequence(jet_fire_right_seq);
- weapon->fire(jet_fire_right_spot, x, y, 0, this);
- }
- else if (ducked)
- {
- set_sequence(duck_fire_right_seq);
- weapon->fire(duck_fire_right_spot, x, y, 0, this);
- }
- else if (standing)
- {
- set_sequence(walk_fire_right_seq);
- weapon->fire(walk_fire_right_spot, x, y, 0, this);
- }
- else
- {
- set_sequence(jump_fire_right_seq);
- weapon->fire(jump_fire_right_spot, x, y, 0, this);
- }
- }
- }
- }
-
- void cCharacter::fire_up()
- {
- if (weapon == 0 || firing)
- return;
-
- // Increase shots fired
-
- shots_fired++;
-
- // Make sure we're standing
-
- stand();
-
- // Fire
-
- firing = weapon->fire_delay;
-
- if (captured != 0)
- {
- delete captured;
- }
- else if (jetpack_active)
- {
- set_sequence(last_move == CHAR_LEFT? jet_fire_up_left_seq:jet_fire_up_right_seq);
- weapon->fire(last_move == CHAR_LEFT? jet_fire_up_left_spot:jet_fire_up_right_spot, x, y, 64, this);
- }
- else if (standing)
- {
- set_sequence(walk_fire_up_seq);
- weapon->fire(walk_fire_up_spot, x, y, 64, this);
- }
- else
- {
- set_sequence(last_move == CHAR_LEFT? jump_fire_up_left_seq:jump_fire_up_right_seq);
- weapon->fire(last_move == CHAR_LEFT? jump_fire_up_left_spot:jump_fire_up_right_spot, x, y, 64, this);
- }
- }
-
- void cCharacter::fire_down()
- {
- if (weapon_down == 0 || firing)
- return;
-
- // Increase shots fired
-
- shots_fired++;
-
- // Fire down
-
- firing = weapon_down->fire_delay;
-
- if (captured != 0)
- {
- delete captured;
- }
- else
- {
- weapon_down->fire(fire_down_spot, x, y, -64, this);
- }
- }
-
- void cCharacter::hit(int armor_power)
- {
- // If already dead do nothing
-
- if (dead)
- return;
-
- // Auch!
-
- set_soundsequence(snd_gothit);
-
- // Impossible to hit?
-
- if (stunned || invulnerable || captured != 0)
- return;
-
- // Substract value from armor
-
- armor -= armor_power;
-
- // Put remaining armor above player
-
- if (armor_power > 0)
- set_text_above(construct("%d%%", armor <= 0? 0:armor), sec);
-
- // Stun if no armor left
-
- if (armor <= 0)
- {
- stuns++;
-
- modify_score(-50);
-
- stunned = next_stun_time;
- invulnerable = next_stun_time + CHAR_INVULNERABLE;
-
- make_dirty();
-
- stand();
- jet_off();
-
- set_horiz_speed(0);
- ay = GRAVITY;
-
- set_sequence(stunned_seq);
-
- make_dirty();
-
- next_stun_time += sec / 2;
-
- armor = orig->params->get_int("*ARMOR", 100);
- }
- }
-
- void cCharacter::push(fix dir, int distance, fix speed, int ignore)
- {
- // Check if dead
-
- if (dead || captured != 0)
- return;
-
- if (distance != 0)
- new_angular_push((fix)0.5, vpush_tx((fix)0.5, distance), apush_tx((fix)0.5, distance), dir);
-
- if (speed != (fix)0)
- add_angular_speed(speed - get_speed(dir), dir);
-
- if (ignore > 0)
- ignore_platforms = ignore;
- }
-
- void cCharacter::capture(cBubble *captor)
- {
- if (captured == 0)
- {
- captured = captor;
-
- stand();
- jet_off();
-
- stop_movement();
-
- set_sequence(captured_seq);
- }
- }
-
- void cCharacter::release()
- {
- if (captured != 0)
- {
- captured = 0;
-
- ay = GRAVITY;
-
- set_animation();
- }
- }
-
- void cCharacter::set_text_above(char *text, int time)
- {
- text_above_char->make_dirty();
- text_above_char->set_text(text);
- text_above_char->set_position(x, y + CHAR_TEXT_DISTANCE);
- text_above_char->make_dirty();
-
- keep_showing_text = time;
- }
-
- void cCharacter::kill_text_above()
- {
- text_above_char->make_dirty();
- text_above_char->set_text(0);
- }
-
- void cCharacter::update_text_above()
- {
- if (keep_showing_text)
- {
- text_above_char->make_dirty();
- text_above_char->set_position(x, y + CHAR_TEXT_DISTANCE);
- text_above_char->make_dirty();
- }
- else
- {
- kill_text_above();
- }
- }
-
- void cCharacter::set_animation()
- {
- if (stunned)
- {
- set_last_in_sequence(stunned_seq);
- }
- else if (captured != 0)
- {
- set_sequence(captured_seq);
- }
- else if (jetpack_active)
- {
- set_sequence(last_move == CHAR_RIGHT? jet_right_seq:jet_left_seq);
- }
- else if (climbing)
- {
- if (abs(vx) > (fix)1 || vy > (fix)1)
- set_sequence(climbing_seq);
- else if (vy < (fix)-1)
- set_inverse_sequence(climbing_seq);
- else
- set_last_in_sequence(climbing_seq);
- }
- else if (ducked)
- {
- set_last_in_sequence(last_move == CHAR_RIGHT? duck_right_seq:duck_left_seq);
- }
- else if (standing)
- {
- if (abs(vx) > (fix)1)
- set_sequence(last_move == CHAR_RIGHT? walk_right_seq:walk_left_seq);
- else
- set_last_in_sequence(last_move == CHAR_RIGHT? walk_right_seq:walk_left_seq);
- }
- else
- set_last_in_sequence(last_move == CHAR_RIGHT? jump_right_seq:jump_left_seq);
- }
-
- int cCharacter::control()
- {
- cGameObject::control();
-
- // Check if we're dead/dying
-
- if (dead)
- {
- set_image(0);
- set_position(x, surface->start);
- stop_movement();
- kill_text_above();
-
- return dead_timer;
- }
-
- // Check if we're captured by something
-
- if (captured != 0)
- {
- if (animation_done())
- set_sequence(captured_seq);
-
- stop_movement();
-
- update_text_above();
-
- return TRUE;
- }
-
- // Set transparent if invulnerable
-
- set_colormap(invulnerable && !stunned? cmap_gray:0);
-
- // Check inpenetrable walls
-
- check_radial_boundaries(circle_bounds, structures, cStructure::check_inpenetrable);
-
- // Do jetpack stuff
-
- if (jetpack_active)
- {
- jetpack_time -= jetpack_timer.raw_delta();
-
- if (jetpack_time <= 0)
- {
- jetpack_time = 0;
-
- jet_off();
- }
- }
-
- // Check if character is on stairs
-
- int was_climbing = climbing;
-
- climbing = !ignore_platforms && is_active() && !jetpack_active
- && check_radial_boundaries(circle_bounds, stairs) != 0;
-
- if (was_climbing && !climbing && vy == (fix)CHAR_CLIMB_SPEED)
- vy = CHAR_JUMP_SPEED;
-
- if ((was_climbing && !climbing) || (!was_climbing && climbing))
- stop_animation();
-
- // Check if character landed
-
- standing = !ignore_platforms && !jetpack_active && !climbing
- && check_resting_on_boundaries(line_bounds, structures);
-
- if (standing)
- vy = 0;
- else
- stand();
-
- // Adjust vertical motion
-
- if (climbing || jetpack_active)
- ay = 0;
- else
- ay = GRAVITY;
-
- // Adjust horizontal motion
-
- ax = 0;
-
- if (!x_on_screen())
- horiz_speed = 0, vx = 0;
- else if (!is_x_pushed())
- vx = horiz_speed;
-
- // Animate
-
- if (animation_done())
- set_animation();
-
- // Set bounds
-
- circle_bounds = !stunned && !ducked? bounds_standing:bounds_ducked;
-
- // Die ?
-
- if (in_water())
- {
- dead = TRUE;
- dead_timer = 3 * sec;
-
- armor = 0;
- circle_bounds = 0;
-
- deaths++;
-
- modify_score(-200);
- }
-
- update_text_above();
-
- return TRUE;
- }
-